/*
 * toneDetector.h
 *
 *  @date 16.04.2014
 *  @author Armin Joachimsmeyer
 *  Email: armin.joachimsmeyer@gmail.com
 *  License: GPL v3 (http://www.gnu.org/licenses/gpl.html)
 *  Sources: https://code.google.com/p/arduino-tone-detector/
 */

#ifndef TONEDETECTOR_H_
#define TONEDETECTOR_H_

/*****************************
 * Timebase stuff
 *****************************/
// sample time values for Prescaler for 16 MHz 4(13*0,25=3,25us),8(6,5),16(13),32(26),64(52),128(104us)
#define PRESCALE4    2
#define PRESCALE32   5
#define PRESCALE64   6
#define PRESCALE128  7

#define TONE_MATCH_INVALID 0
#define TONE_MATCH_LOWER   1
#define TONE_MATCH         2
#define TONE_MATCH_HIGHER  3

#define SIZE_OF_PERIOD_LENGTH_ARRAY_FOR_PLAUSI 64

// Signal plausi codes
#define SIGNAL_STRENGTH_LOW 0
#define SIGNAL_FIRST_PLAUSI_FAILED 1
#define SIGNAL_DISTRIBUTION_PLAUSI_FAILED 2
#define SIGNAL_MAX_ERROR_CODE 2

struct ToneDetectorControlStruct {

    /*
     * Raw frequency data from aquireData
     */
    uint16_t Frequency10HzActual; // Frequency in 10 HZ units or "error code"  SIGNAL_...
    uint16_t TriggerLevelUpper;
    uint16_t TriggerLevelLower;

    /*
     * Plausibility for more stable detection results of noisy and weak signals
     */
    uint16_t RawVoltageMinDelta; // Min delta U (raw ADC value) for valid signal strength. 0x40=312mV, 0x20=156 mVolt
    uint8_t PeriodCountMin; // Min count of periods in 512 samples for reasonable values (37,56 Hz per count) => 16 periods -> 601 Hz
    uint8_t PeriodCountMax; // Max count of periods in 512 samples for reasonable values
    uint8_t PeriodCountActual; // Actual count of periods in 512 samples - !!! cannot be greater than SIZE_OF_PERIOD_LEGTH_ARRAY_FOR_PLAUSI - 1)!!!
    uint16_t PeriodCountFirstPosition; // position of first detection of a trigger in 512 samples
    uint16_t PeriodCountLastPosition; // position of last detection of a trigger in 512 samples
    uint8_t PeriodLength[SIZE_OF_PERIOD_LENGTH_ARRAY_FOR_PLAUSI]; // Array of period length of the signal for plausi

    uint8_t MaxMatchDropoutCount; // threshold for allowed PeriodActual == 0 conditions before match = TONE_MATCH_INVALID
    uint8_t MatchDropoutCount; // count for allowed PeriodActual == 0 conditions before match = TONE_MATCH_INVALID

    /*
     * Parameters for filtering / matching of frequency
     */
    uint16_t Frequency10HzMin;
    uint16_t Frequency10HzMax;
    uint16_t Frequency10HzFiltered; // internal value - low pass filter value for frequency

    uint8_t ToneMatch; // TONE_MATCH_INVALID, TONE_MATCH_LOWER, TONE_MATCH, TONE_MATCH_HIGHER
    uint16_t MatchLowPassFiltered; // internal value - low pass filter value for computing ToneMatchFiltered
    uint8_t ToneMatchFiltered; // "value" of ToneMatches processed by low pass filter

};

extern ToneDetectorControlStruct ToneDetectorControl;

void setToneDetectorControlDefaults(void);
void analyzeSignal(uint8_t aPrescaleRegisterValue);
void doPlausi(void);
void computeMatch(void);

#endif /* TONEDETECTOR_H_ */
